package org.black.missedCall2.reply.broadcastReceiver;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.black.missedCall2.MissedCallConstant;
import org.black.missedCall2.reply.ReplyConstant;
import org.black.missedCall2.reply.content.ReplyContentProviderMetaData;

import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog;
import android.telephony.PhoneStateListener;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.util.Log;

public class PhoneStateReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(final Context context, Intent intent) {
		Log.d(MissedCallConstant.APP_TAG, "receive phone state change.");
		TelephonyManager telephonyManager = (TelephonyManager) context
				.getSystemService(Service.TELEPHONY_SERVICE);
		ReplyPhoneStateListener replyPhoneStateListener = new ReplyPhoneStateListener(
				context);
		telephonyManager.listen(replyPhoneStateListener,
				PhoneStateListener.LISTEN_CALL_STATE);
		telephonyManager.listen(replyPhoneStateListener,
				PhoneStateListener.LISTEN_NONE);
	}

	class ReplyPhoneStateListener extends PhoneStateListener {
		private Context context;

		public ReplyPhoneStateListener(Context context) {
			this.context = context;
		}

		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			SharedPreferences sharedPreferences = this.context
					.getApplicationContext().getSharedPreferences(
							MissedCallConstant.MISSED_CALL_PREFERENCE,
							Context.MODE_WORLD_WRITEABLE
									| Context.MODE_WORLD_READABLE);

			int olderSharedPreference = sharedPreferences.getInt(
					ReplyConstant.PREFERENCE_OLDER_PHONE_STATE, -1);
			Log.d(ReplyConstant.REPLY_TAG, "Old phone state: "
					+ olderSharedPreference);

			SharedPreferences.Editor editor = sharedPreferences.edit();
			editor.putInt(ReplyConstant.PREFERENCE_OLDER_PHONE_STATE, state);
			editor.commit();
			Log.d(ReplyConstant.REPLY_TAG, "Write phone state: " + state);

			switch (state) {
			case TelephonyManager.CALL_STATE_IDLE:
				if (olderSharedPreference == TelephonyManager.CALL_STATE_OFFHOOK
						|| olderSharedPreference == TelephonyManager.CALL_STATE_RINGING) {
					Thread replyThread = new Thread(new ReplyThread(state,
							incomingNumber, context));
					replyThread.start();
				}
				break;
			case TelephonyManager.CALL_STATE_OFFHOOK:
				break;
			case TelephonyManager.CALL_STATE_RINGING:
				break;
			}
		}
	}

	class ReplyThread implements Runnable {
		private int state;
		private String incomingNumber;
		private Context context;

		public ReplyThread(int state, String incomingNumber, Context context) {
			this.state = state;
			this.incomingNumber = incomingNumber;
			this.context = context;
		}

		@Override
		public void run() {
			Log.i(ReplyConstant.REPLY_TAG, "Phone state change. state:" + state
					+ ", incomingNumber: " + incomingNumber);
			try {
				Date date = new Date();
				SharedPreferences sharedPreferences = this.context
						.getApplicationContext().getSharedPreferences(
								MissedCallConstant.MISSED_CALL_PREFERENCE,
								Context.MODE_WORLD_WRITEABLE
										| Context.MODE_WORLD_READABLE);
				long lastMissedCallTime = sharedPreferences.getLong(
						ReplyConstant.PREFERENCE_LAST_MISSED_CALL_TIME,
						Long.MIN_VALUE);
				sharedPreferences
						.edit()
						.putLong(
								ReplyConstant.PREFERENCE_LAST_MISSED_CALL_TIME,
								date.getTime()).commit();
				Log.d(ReplyConstant.REPLY_TAG, "Put " + date.getTime()
						+ " into "
						+ ReplyConstant.PREFERENCE_LAST_MISSED_CALL_TIME);

				if (lastMissedCallTime > Long.MIN_VALUE) {
					Uri allCalls = Uri.parse("content://call_log/calls");
					Cursor cursor = this.context.getContentResolver().query(
							allCalls,
							null,
							"type = " + CallLog.Calls.MISSED_TYPE
									+ " AND date >= " + lastMissedCallTime,
							null, "date DESC");
					if (cursor != null) {
						Set<String> missedCallNumbers = new HashSet<String>();

						if (cursor.moveToFirst() == true) {
							do {
								String number = cursor.getString(cursor
										.getColumnIndex(CallLog.Calls.NUMBER));
								if (number != null) {
									missedCallNumbers.add(number.trim());
								}
							} while (cursor.moveToNext());
							
						}
						cursor.close();

						if (missedCallNumbers.size() > 0) {
							Uri replySettings = Uri.parse("content://"
									+ ReplyContentProviderMetaData.AUTHORITY
									+ "/"
									+ ReplyContentProviderMetaData.BASE_PATH);
							Cursor replyCursor = this.context
									.getContentResolver()
									.query(replySettings,
											null,
											ReplyContentProviderMetaData.COLUMN_SHOULD_REPLY
													+ " = 1", null, null);
							replyCursor.close();
							SmsManager smsManager = SmsManager.getDefault();
							Intent sentIntent = new Intent(
									ReplyConstant.SMS_SENT_INTENT);
							sentIntent.putExtra(
									ReplyConstant.INTENT_DESTINATION_ADDRESS,
									incomingNumber);
							sentIntent.putExtra(ReplyConstant.INTENT_TEXT,
									"I'm driving");
							PendingIntent sentPendingIntent = PendingIntent
									.getBroadcast(this.context, 0, sentIntent,
											PendingIntent.FLAG_UPDATE_CURRENT);

							Intent deliverIntent = new Intent(
									ReplyConstant.SMS_DELIVER_INTENT);
							PendingIntent deliverPendingIntent = PendingIntent
									.getBroadcast(this.context, 0,
											deliverIntent,
											PendingIntent.FLAG_UPDATE_CURRENT);

							smsManager.sendTextMessage(this.incomingNumber,
									null, "789", sentPendingIntent,
									deliverPendingIntent);
						}
					}
				}
			} catch (Exception e) {
				Log.e(ReplyConstant.REPLY_TAG,
						"Unable to handle sending sms task.", e);
			} finally {
				this.incomingNumber = null;
				this.context = null;
			}
			Log.d(ReplyConstant.REPLY_TAG, "End reply thread!");
		}
	}

}
